package com.business.lgh.naocs.naming.web;

import com.business.lgh.nacos.api.naming.common.CommonParams;
import com.business.lgh.nacos.core.utils.WebUtils;
import com.business.lgh.naocs.naming.core.ServerMemberManager;
import com.business.lgh.naocs.naming.core.pojo.Member;
import javafx.fxml.Initializable;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lgh
 * @version V1.0
 * @Package com.business.lgh.naocs.naming.web
 * @date 2020/6/28 8:09 下午
 */

public class DistorFillter implements Filter {

    private static final Object HTTP = "http://";
    @Autowired
    RequestMappingHandlerMapping handlerMapping;

    @Autowired
    DistroMapper distroMapper;

    OkHttpClient client = new OkHttpClient();

    @Autowired
    ServerMemberManager serverMemberManager;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //转型为HttpServletRequest
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        final String serviceName = WebUtils.optional(request, CommonParams.SERVICE_NAME,StringUtils.EMPTY);

        try {
            //获取HandlerMethod对象
            HandlerMethod handlerMethod = (HandlerMethod) handlerMapping.getHandler(request).getHandler();
            if (handlerMethod != null) {
                int targetIndex = -1;
                //判断是否有CanDistro注解
                if (handlerMethod.hasMethodAnnotation(CanDistro.class) && ((targetIndex = distroMapper.responsible(serviceName)) != -1)) {
                    //获取要转发的服务地址
                    String targetServer = distroMapper.getServer(targetIndex);
                    //判断目标地址是否不为空，且不是本地地址匹配
                    if (StringUtils.isNotBlank(targetServer) && !targetServer.contains(serverMemberManager.getLocalAddress())) {
//
//                      //构建URL
                        String url = HTTP + targetServer + new URI(request.getRequestURI()).getPath();
                        //添加参数
                        String encodedContent = encodingParams(request, "UTF-8");
                        url += (StringUtils.isEmpty(encodedContent)) ? "" : ("?" + encodedContent);
//
//                        //构建请求参数
//                        Request.Builder builder = new Request.Builder();
//                        builder.url(url);
//                        builder.headers(getHeaders(request));
//                        builder.method(request.getMethod(), request.ge);
//                        builder.post(new FormBody.Builder().build());

                        //发送请求
                        Response resp = client.newCall(create(request, url)).execute();
                        WebUtils.response(response, resp.body().string(), resp.code());
                        return;
                    }
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    private String encodingParams(HttpServletRequest request, String encoding) throws UnsupportedEncodingException {
        Enumeration<String> parameterNames = request.getParameterNames();
        StringBuilder sb = new StringBuilder();

        while (parameterNames.hasMoreElements()) {
            String element = parameterNames.nextElement();
            if (StringUtils.isEmpty(request.getParameter(element))) {
                continue;
            }

            sb.append(element).append("=");
            sb.append(URLEncoder.encode(request.getParameter(element), encoding));
            sb.append("&");
        }

        if (sb.length() > 0) {
            sb = sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }


    /**
     * 转化头部参数为okhttp的
     *
     * @param request
     * @return
     */
    private Headers get(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        //拷贝header头
        Headers.Builder headersBuilder = new Headers.Builder();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headName = headerNames.nextElement();
            headersBuilder.add(headName, request.getHeader(headName));
        }
        return headersBuilder.build();
    }


    Request create(HttpServletRequest request, String url) throws IOException {

        final HttpUrl targetUrl = HttpUrl.get(URI.create(url));

//        final String originalBody = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        //获取内容
        BufferedReader reader = request.getReader();
        String line;
        StringBuilder sb = new StringBuilder();
        reader.reset();
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        String originalBody = sb.toString();

        final RequestBody requestBody = RequestBody.create(MediaType.parse(request.getContentType()), originalBody);

        final Request httpRequest = new Request.Builder()
                .post(requestBody)
                .url(targetUrl)
                .build();
        return httpRequest;
    }

}
